<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引用aixos -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <!-- 引入进度条相关文件 -->
    <link href="https://cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/nprogress/0.2.0/nprogress.js"></script>
</head>
<body>
    <h1>axios请求拦截器</h1>
    <input type="text" id="ipt">
    <button id="btn">发送请求</button>
    <button id="cancel">取消请求</button>
     <script>
        /*
        创建一个axios实例 并配置这个实例

        */
      const myAxios = axios.create({
        //设置公用地址
        baseURL: "/",
        //设置延时时间
        timeout: 100000,
        //在头部中设置信息
        headers: {} 
       })

       //添加请求拦截器,处理请求数据的相关逻辑
       myAxios.interceptors.request.use(config=>{
        /*
            config是请求配置信息
            config的headers头里面有common属性
        */
        // alert("拦截成功")

        //在发送请求之前获取token,并让请求头携带token作为访问的唯一标识
        // 模拟token
        const token = "jsfsfKHFFNpwg.sfaffbniaixcvnei.smwqudinndwso"
        console.log("config",config);
        // 设置token
        config.headers.token = token
        // 在开始请求数据的地方可以加上进度条用以给用户一定的提示,提高用户体验
        NProgress.start()
        // 返回config也叫放行
        return config
       },error=>{
        // 如果请求的过程中出错,拦截器会做什么
        console.log("error",error);
       })

       //添加响应拦截器,处理响应数据的相关逻辑
       myAxios.interceptors.response.use(response=>{
        console.log("response",response);
        


        // 在处理完相关逻辑之后,添加结束进度条语句,返回需要的数据
        NProgress.done()

        // 对请求到的结果进行处理,拿到正确的部分,如果有错误直接交给异常处理
        //服务端只要做出了响应,无论正确与否,都表示请求成功,
        //但是我们只需要拿取正确的数据,
        //前后端交互数据,一般都会设置交换的自定义状态码,以区别是否成功获取数据
        if(response.data.code!==10000){
            // 如果直接把错误信息返回出去,
            //则返回的结构是成功状态的promise,值为错误信息
            //那么await接收的值就是这个成功状态的promise的值,也就是await此时的值为;错误信息
            // return response.data.msg//result 查询失败
            /*将错误快速的包装成失败的promise实例,则在try catch内部直接被视为错误处理*/
            return Promise.reject(response.data.msg)
        }
        
        return response.data.data
       })

     //使用myAioxs中的get请求获取相关数据

     //获取dom对象
     const oIpt = document.getElementById("ipt")
     const oBtn = document.getElementById("btn")
     const oCancel = document.getElementById("cancel")

     //axios.CancelToken可以拿到取消请求的构造函数
     const CancelToken = axios.CancelToken
     let cancel = null
     //点击之后发送请求
     oBtn.onclick = async function(){
        //点进之后获取的数据才是用户输入的数据
        const iptValue  = oIpt.value 
        try{
            //get请求,参数1是访问地址,参数2是配置对象,需要保存返回值
            //await直接接收其后成功状态的promise实例的值
            //axios的响应结构http://www.axios-js.com/zh-cn/docs/#%E5%93%8D%E5%BA%94%E7%BB%93%E6%9E%84
            const result = await myAxios.get("/user",{
                params: {
                    // 动态设置userId
                    // userId: "001"
                    userId: iptValue
                },
                //在配置对象中配置一个cancelToken配置项,值为实例化的CancelToken
                // cancelToken: new CancelToken(function executor(c) {
                // // executor 函数接收一个 cancel 函数作为参数
                // // console.log(c);
                // // 一旦请求中断,则会交给catch处理
                // cancel = c;
                // })
            })
            // cancel()
            // result是是一个对象,其中data对象中有后端响应的数据
            console.log("result",result);//{data: {…}, status: 200, statusText: 'OK', headers: {…}, config: {…}, …}
            // 未用响应拦截器处理返回的数据的时候,响应拦截器处理后拿不到这个值,直接返回undefined
            // console.log(result.data);//{code: 10000, msg: '查询成功', data: {…}}
        
        
        }catch(e){
            // 处理try中的错误

            console.log(e,"出现错误");
        }
       
     }
     //取消点击事件
    //  oCancel.onclick = function(){
    //     cancel()
    //  }

     </script>
</body>
</html>